home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / Lose Your Marbles! 1.0 / source / ls code ƒ / ls load-save.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  5.2 KB  |  223 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        ls load-save.c
  4.  
  5. Purpose:    This module handles loading and saving games on disk.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program in a file named "GNU General Public License".
  19. If not, write to the Free Software Foundation, 675 Mass Ave,
  20. Cambridge, MA 02139, USA.
  21.  
  22. \**********************************************************************/
  23.  
  24. #include "error.h"
  25. #include "ls load-save.h"
  26. #include "file interface.h"
  27. #include "ls.h"
  28. #include "program globals.h"
  29. #include "dialogs.h"
  30. #include "environment.h"
  31. #include "util.h"
  32. #include "Script.h"
  33.  
  34. FSSpec            gameFile;
  35. Boolean            deleteTheThing;
  36.  
  37. typedef struct
  38. {
  39.     unsigned short    version;            /* for forward compatibility */
  40.     unsigned short    crc;                /* checksum */
  41.     
  42.     short            numRows;            /* number of rows in saved board */
  43.     short            numColumns;            /* number of columns in saved board */
  44.     short            currentRow;            /* currently highlighted row */
  45.     short            currentColumn;        /* currently highlighted column */
  46.     short            numMoves;            /* number of moves so far */
  47.     short            theboard[MAX_ROWS][MAX_COLS];        /* actual board */
  48.     Point            themoves[MAX_ROWS*MAX_COLS];        /* all moves array */
  49. } SaveStruct;
  50.  
  51. void InitLoadSave(void)
  52. {
  53.     gameFile.name[0]=0x00;
  54.     deleteTheThing=FALSE;
  55. }
  56.  
  57. void LoadSaveDispatch(Boolean isLoad, Boolean useOldGame)
  58. {
  59.     if (isLoad)
  60.     {
  61.         if (GetSourceFile(&gameFile, FALSE, FALSE))
  62.             HandleError(GetSavedGame(&gameFile), FALSE);
  63.     }
  64.     else
  65.     {
  66.         useOldGame=useOldGame&&(gameFile.name[0]!=0x00);
  67.         if (useOldGame ? TRUE : GetDestFile(&gameFile, &deleteTheThing, "\pSave game as..."))
  68.             HandleError(SaveGame(gameFile), FALSE);
  69.     }
  70. }
  71.  
  72. enum ErrorTypes SaveGame(FSSpec gameFile)
  73. {
  74.     OSErr            theError;
  75.     short            thisFile;
  76.     long            count;
  77.     SaveStruct        data;
  78.     short            i,j;
  79.     
  80.     data.numRows=gNumRows;
  81.     data.numColumns=gNumColumns;
  82.     data.currentRow=gCurrentRow;
  83.     data.currentColumn=gCurrentColumn;
  84.     for (i=0; i<MAX_ROWS; i++)
  85.         for (j=0; j<MAX_COLS; j++)
  86.             data.theboard[i][j]=Board[i][j];
  87.     for (i=0; i<MAX_ROWS*MAX_COLS; i++)
  88.         data.themoves[i]=gMoves[i];
  89.     data.version=SAVE_VERSION;
  90.     data.crc=0;
  91.     data.crc=TheChecksum((Ptr)(&data), sizeof(SaveStruct));
  92.     
  93.     if (deleteTheThing)
  94.     {
  95.         if (gHasFSSpecs)
  96.             FSpDelete(&gameFile);
  97.         else
  98.             HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
  99.     }
  100.     FlushVol(0L, gameFile.vRefNum);
  101.     
  102.     if (gHasFSSpecs)
  103.         theError=FSpCreate(&gameFile, CREATOR, SAVE_TYPE, smSystemScript);
  104.     else
  105.         theError=HCreate(gameFile.vRefNum, gameFile.parID,
  106.                         gameFile.name, CREATOR, SAVE_TYPE);
  107.     FlushVol(0L, gameFile.vRefNum);
  108.     
  109.     if (theError!=noErr)
  110.         return kCantCreateGame;
  111.     
  112.     if (gHasFSSpecs)
  113.         theError=FSpOpenDF(&gameFile, fsRdWrPerm, &thisFile);
  114.     else
  115.         theError=HOpen(gameFile.vRefNum, gameFile.parID,
  116.                         gameFile.name, fsRdWrPerm, &thisFile);
  117.     
  118.     if (theError!=noErr)
  119.         return kCantOpenGameToSave;
  120.  
  121.     count=sizeof(SaveStruct);
  122.     theError=SetEOF(thisFile, count);
  123.     if (theError!=noErr)
  124.     {
  125.         FSClose(thisFile);
  126.         return kDiskFull;
  127.     }
  128.     
  129.     SetFPos(thisFile, 1, 0L);
  130.     theError=FSWrite(thisFile, &count, &data);
  131.     
  132.     FSClose(thisFile);
  133.     FlushVol(0L, gameFile.vRefNum);
  134.  
  135.     if (theError!=noErr)
  136.     {
  137.         if (gHasFSSpecs)
  138.             FSpDelete(&gameFile);
  139.         else
  140.             HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
  141.         
  142.         gameFile.name[0]=0x00;
  143.         return kCantWriteGame;
  144.     }
  145.     else deleteTheThing=TRUE;
  146.     
  147.     return allsWell;
  148. }
  149.  
  150. enum ErrorTypes GetSavedGame(FSSpec *gameFile)
  151. {
  152.     short            thisFile;
  153.     long            count;
  154.     short            i,j;
  155.     SaveStruct        data;
  156.     OSErr            theError;
  157.     unsigned short    checksum, savedChecksum;
  158.     
  159.     if (gHasFSSpecs)
  160.         theError=FSpOpenDF(gameFile, fsRdPerm, &thisFile);
  161.     else
  162.         theError=HOpen(gameFile->vRefNum, gameFile->parID, gameFile->name, fsRdPerm, &thisFile);
  163.     
  164.     if (theError!=noErr)
  165.         return kCantOpenGameToLoad;
  166.     
  167.     count=sizeof(SaveStruct);
  168.     SetFPos(thisFile, 1, 0L);
  169.     theError=FSRead(thisFile, &count, &data);
  170.     FSClose(thisFile);
  171.     
  172.     if (theError!=noErr)
  173.         return kCantLoadGame;
  174.     
  175.     deleteTheThing=TRUE;
  176.     
  177.     if (data.version!=SAVE_VERSION)
  178.         return kSaveVersionNotSupported;
  179.     
  180.     savedChecksum=data.crc;
  181.     data.crc=0;
  182.     checksum=TheChecksum((Ptr)(&data), sizeof(SaveStruct));
  183.     if (checksum!=savedChecksum)
  184.     {
  185.         gameFile->name[0]=0x00;
  186.         return kBadChecksum;
  187.     }
  188.     
  189.     gNumRows=data.numRows;
  190.     gNumColumns=data.numColumns;
  191.     gCurrentRow=data.currentRow;
  192.     gCurrentColumn=data.currentColumn;
  193.     gNumMoves=data.numMoves;
  194.     for (i=0; i<MAX_ROWS; i++)
  195.         for (j=0; j<MAX_COLS; j++)
  196.             Board[i][j]=data.theboard[i][j];
  197.     for (i=0; i<MAX_ROWS*MAX_COLS; i++)
  198.         gMoves[i]=data.themoves[i];
  199.     
  200.     StartGame();
  201.     
  202.     return allsWell;
  203. }
  204.  
  205. unsigned short TheChecksum(Ptr input, unsigned short len)
  206. {
  207.     unsigned short    i;
  208.     Boolean            shiftedOut;
  209.     unsigned short    checksum;
  210.     
  211.     checksum=0;
  212.     for (i=0; i<len; i++)
  213.     {
  214.         shiftedOut=checksum&0x8000;
  215.         checksum+=*((unsigned char*)((long)input+i));
  216.         checksum<<=1;
  217.         if (shiftedOut)
  218.             checksum^=0xdead;
  219.     }
  220.     
  221.     return checksum;
  222. }
  223.